package pl.freetimetool.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import pl.freetimetool.common.AccountRoles;
import pl.freetimetool.domain.Account;
import pl.freetimetool.domain.AccountRole;
import pl.freetimetool.domain.Manager;
import pl.freetimetool.exceptions.UserExistsException;
import pl.freetimetool.service.AccountService;
import pl.freetimetool.view.editor.ManagerEditor;

@Controller
public class ManagerController {

	@Autowired
	AccountService accountService;

	@RequestMapping(value = "/manager/delete", method = RequestMethod.GET)
	public ModelAndView delete() {
		final ModelAndView mav = new ModelAndView("/manager/delete");
		mav.addObject("manager", new Manager());
		return mav;
	}

	@RequestMapping(value = "/manager/delete", method = RequestMethod.POST)
	public ModelAndView delete(@Valid final Manager manager) {
		final ModelAndView mav = new ModelAndView("manager/delete");

		if (manager != null) {
			this.accountService.removeAccount(manager.getUsername());
		}

		mav.setViewName("redirect:/manager/deleteConfirmed");
		return mav;
	}

	@RequestMapping(value = "/manager/deleteConfirmed", method = RequestMethod.GET)
	public ModelAndView removeDetails() {
		final ModelAndView mav = new ModelAndView("common/deleteConfirmed");
		mav.addObject("acc", "Manager");
		return mav;
	}

	@RequestMapping(value = "/manager/add", method = RequestMethod.GET)
	public ModelAndView add() {
		final ModelAndView mav = new ModelAndView("/manager/add");
		final ArrayList<AccountRole> roles = new ArrayList<AccountRole>();
		roles.add(new AccountRole(AccountRoles.WORKER));
		mav.addObject("workers", this.accountService.listAccounts(roles));

		mav.addObject("manager", new Manager());
		return mav;
	}

	@RequestMapping(value = "/manager/add", method = RequestMethod.POST)
	public ModelAndView add(@Valid final Manager manager, final BindingResult result) {
		final ModelAndView mav = new ModelAndView("manager/add");
		if (!manager.getPassword().equals(manager.getRepeatedPassword())) {
			result.addError(new FieldError("manager", "repeatedPassword", "notEqual"));
		}

		if (result.hasErrors()) {
			mav.addObject("manager", manager);
			return mav;
		}

		final List<AccountRole> ar = new ArrayList<AccountRole>();
		ar.add(new AccountRole(AccountRoles.MANAGER));

		manager.getWorkers();

		try {
			this.accountService.registerAccount(manager, ar);
		} catch (final UserExistsException e) {
			e.printStackTrace();
		}

		mav.setViewName("redirect:/manager/showDetails/" + manager.getUsername());
		return mav;
	}
	@RequestMapping(value = "/manager/showDetails/{username}", method = RequestMethod.GET)
	public ModelAndView details(@PathVariable("username") final String username) {
		final ModelAndView mav = new ModelAndView("manager/showDetails");
		mav.addObject("manager", this.accountService.getAccount(username));
		return mav;
	}

	@RequestMapping(value = "/manager/showManagers", method = RequestMethod.GET)
	public ModelAndView showAll() {
		final ModelAndView mav = new ModelAndView("manager/getAll");
		return mav;
	}

	@InitBinder
	public void initBinder(final WebDataBinder dataBinder) {
		dataBinder.registerCustomEditor(Manager.class, new ManagerEditor(this.accountService));
	}

	@ModelAttribute("managers")
	public Collection<Account> listManagers() {
		final ArrayList<AccountRole> roles = new ArrayList<AccountRole>();
		roles.add(new AccountRole(AccountRoles.MANAGER));
		return this.accountService.listAccounts(roles);
	}

	@ModelAttribute("workers")
	public Collection<Account> listWorkers() {
		final ArrayList<AccountRole> roles = new ArrayList<AccountRole>();
		roles.add(new AccountRole(AccountRoles.WORKER));
		return this.accountService.listAccounts(roles);
	}

	@RequestMapping(value = "/manager/details.html", method = RequestMethod.GET)
	public ModelAndView assignWorkers() {
		final ModelAndView mav = new ModelAndView("manager/managerManagement/managerDetails");
		return mav;
	}

	@RequestMapping(value = "/manager/managerPanel.html", method = RequestMethod.GET)
	public ModelAndView managerPanel() {
		final ModelAndView mav = new ModelAndView("manager/managerManagement/managerManagementPanel");
		mav.addObject("manager", new Manager());
		return mav;
	}

	@RequestMapping(value = "/manager/managerPanel.html", method = RequestMethod.POST)
	public ModelAndView managerPanel(@Valid final Manager manager, final BindingResult result) {
		final ModelAndView mav = new ModelAndView("manager/managerManagement/managerManagementPanel");
		mav.addObject("selectedManager", this.accountService.getAccount(manager.getUsername()));
		return mav;
	}
}
